home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- *
- * FILE: mkmotd.c
- *
- * PURPOSE: Make a message-of-the-day database
- *
- * DESCRIPTION: A message-of-the-day database has a specific format that
- * must be followed so that all programs that use the data
- * can use it correctly.
- *
- * Most of the records in the database are simply null-
- * terminated text strings that contain messages, one per
- * record. The database's first record is special, and contains
- * the following information:
- *
- * mode (4 bytes, unsigned) - this field describes how the
- * text records in the rest of the database are used:
- *
- * mode = 1: only the first text record is used, and it is
- * used over and over again. PalmJournal can use
- * this mode to insert a standard text template
- * into every day's new journal entry.
- * mode = 2: each record is used in turn, starting with the
- * first text record. This is useful for a message
- * of the day, where the particular day doesn't
- * matter. The most recently-used record's index
- * can be stored in the last_used field (below)
- * to keep things in order. When the last record
- * has been used, the program starts over again
- * at the first record.
- * mode = 3: only the first 7 records are used, based on the
- * day of the week. The first record is for Sunday,
- * the second for Monday, etc. PalmJournal can use
- * this mode to provide a different text template
- * for each weekday's journal entry.
- * mode = 4: there must be at least 366 records for this mode.
- * Each record corresponds to a day of the year.
- * **NOTE: Feruary 29 is treated specially... it's
- * always the 366th day. This way, each day's number
- * within the year is constant, regardless of leap
- * year.
- *
- * last_used (2 bytes, unsigned) - this field is really only
- * useful for mode 2, since the other modes always determine
- * which record number to use by some other method. Only mode
- * 2 requires the program to remember which record was used
- * last.
- *
- * This program takes a single command-line argument: the mode
- * number for the resulting database (see above).
- *
- * This program reads the input file "motddb.txt" (in the
- * current directory) as the source of the text records for the
- * database. Each record in the file must be on a single line,
- * and empty lines are not allowed. Records may include linefeeds
- * as "\n" in the text.
- *
- * This program creates the file "motddb.pdb" in the current
- * directory. This program also assumes that it is being run
- * on an INTEL-like processor, and so will byte-swap short and
- * long integers. Just change the SSwap and LSwap routines if
- * you compile this on some other architecture.
- *
- * REVISION HISTORY:
- * v 1.0 Original release
- * v 1.1 Increased maximum line length to 4096, fixed international
- * character compatibility, added command-line parameters
- ****************************************************************************/
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #define TRUE 1
- #define FALSE 0
-
- /* this is a PALM OS standard -- do not change */
- #define DB_NAME_SIZE 32
-
- /* this is an arbitrary number, make it whatever you want */
- #define MAX_RECORDS 400
-
- /* again, an arbitrary number, for convenient programming */
- #define MAX_LINE_LENGTH 4096
-
- /* the linefeed character */
- #define LF 0x0a
-
- /* the file names */
- char *outfile_name = "motddb.pdb";
- char *infile_name = "motddb.txt";
-
- /* there shouldn't be any need to change these initial values */
- char db_name[DB_NAME_SIZE];
- unsigned short db_attributes = 0;
- unsigned short db_version = 0;
- unsigned long db_creation_date = 0x32cb1cc2;
- unsigned long db_modification_date = 0x32cb1cc2;
- unsigned long db_last_backup_date = 0x32cb1cc2;
- unsigned long db_modification_number = 1;
- unsigned long db_app_info_id = 0;
- unsigned long db_sort_info_id = 0;
- unsigned char db_type[4] = {'D', 'a', 't', 'a'};
- unsigned char db_creator[4] = {'C', 'k', 's', '4'};
- unsigned long db_unique_id_seed = 0;
- unsigned long db_next_record_list_id = 0;
- unsigned short db_num_records = 0;
-
- unsigned char rec_attributes = 0;
-
- /* this is a pointer to the buffer that holds the records when they are
- read in */
- char *record[MAX_RECORDS];
-
- /* local function prototypes */
- long get_records(void);
- unsigned long LSwap(unsigned long l);
- unsigned short SSwap(unsigned short s);
- char *transform(char *s);
-
- /***************************************************************************
- * main()
- ***************************************************************************/
- main(int argc, char * argv[]) {
- FILE *outfile;
- unsigned long mode = 2;
- unsigned short last_used = 0;
- unsigned short i;
- long pad = 0;
- unsigned long offset = 80;
- unsigned char temp_char;
- unsigned short temp_short;
- unsigned long temp_long;
-
- for (i = 1; i < argc; i++) {
- if (argv[i][0] == '-') {
- switch (argv[i][1]) {
- case 'm':
- if (argc > (i + 1))
- mode = atol(argv[i + 1]);
- break;
- case 'i':
- if (argc > (i + 1))
- infile_name = argv[i + 1];
- break;
- case 'o':
- if (argc > (i + 1))
- outfile_name = argv[i + 1];
- break;
- default:
- printf("usage: mkmotd [-m mode] [-i input file] [-o output file]\n");
- printf(" default mode is 2\n");
- printf(" default input file is motddb.txt\n");
- printf(" default output file is motddb.pdb\n");
- return(1);
- break;
- }
- }
- }
-
- printf("mkmotd: mode = %ld\ninput file = %s\noutput file = %s\n", mode, infile_name, outfile_name);
-
- outfile = fopen(outfile_name, "wb");
- if (outfile) {
-
- memset(db_name, 0, DB_NAME_SIZE);
- strcpy(db_name, "MOTDDB");
- fwrite(db_name, DB_NAME_SIZE, 1, outfile);
-
- temp_short = SSwap(db_attributes);
- fwrite(&temp_short, sizeof(temp_short), 1, outfile);
-
- temp_short = SSwap(db_version);
- fwrite(&temp_short, sizeof(temp_short), 1, outfile);
-
- temp_long = LSwap(db_creation_date);
- fwrite(&temp_long, sizeof(temp_long), 1, outfile);
-
- temp_long = LSwap(db_modification_date);
- fwrite(&temp_long, sizeof(temp_long), 1, outfile);
-
- temp_long = LSwap(db_last_backup_date);
- fwrite(&temp_long, sizeof(temp_long), 1, outfile);
-
- temp_long = LSwap(db_modification_number);
- fwrite(&temp_long, sizeof(temp_long), 1, outfile);
-
- temp_long = LSwap(db_app_info_id);
- fwrite(&temp_long, sizeof(temp_long), 1, outfile);
-
- temp_long = LSwap(db_sort_info_id);
- fwrite(&temp_long, sizeof(temp_long), 1, outfile);
-
- fwrite(&db_type, 4, 1, outfile);
- fwrite(&db_creator, 4, 1, outfile);
-
- temp_long = LSwap(db_unique_id_seed);
- fwrite(&temp_long, sizeof(temp_long), 1, outfile);
-
- temp_long = LSwap(db_next_record_list_id);
- fwrite(&temp_long, sizeof(temp_long), 1, outfile);
-
- db_num_records = get_records() + 1;
- temp_short = SSwap(db_num_records);
- fwrite(&temp_short, sizeof(temp_short), 1, outfile);
-
- offset += (db_num_records * 8);
-
- /* write the record index for the special first record */
- temp_long = LSwap(offset);
- fwrite(&temp_long, sizeof(temp_long), 1, outfile);
- fwrite(&rec_attributes, sizeof(rec_attributes), 1, outfile);
- temp_char = 20;
- fwrite(&temp_char, sizeof(temp_char), 1, outfile);
- temp_char = 0;
- fwrite(&temp_char, sizeof(temp_char), 1, outfile);
- temp_char = 0;
- fwrite(&temp_char, sizeof(temp_char), 1, outfile);
- offset += 6;
-
- /* write the record indeces for the text records */
- for (i = 0; i < db_num_records - 1; i++) {
- temp_long = LSwap(offset);
- fwrite(&temp_long, sizeof(temp_long), 1, outfile);
- fwrite(&rec_attributes, sizeof(rec_attributes), 1, outfile);
- temp_char = 20;
- fwrite(&temp_char, sizeof(temp_char), 1, outfile);
- temp_char = ((i+1) & 0xff00) >> 8;
- fwrite(&temp_char, sizeof(temp_char), 1, outfile);
- temp_char = ((i+1) & 0x00ff);
- fwrite(&temp_char, sizeof(temp_char), 1, outfile);
- offset += strlen(record[i]) + 1;
- }
-
- fwrite(&pad, 2, 1, outfile);
-
- /* write the special first record */
- temp_long = LSwap(mode);
- fwrite(&temp_long, sizeof(temp_long), 1, outfile);
- temp_short = SSwap(last_used);
- fwrite(&temp_short, sizeof(temp_short), 1, outfile);
-
- /* write the text records */
- for (i = 0; i < db_num_records - 1; i++) {
- fwrite(record[i], strlen(record[i]) + 1, 1, outfile);
- }
-
- fclose(outfile);
- }
- }
-
- /****************************************************************************
- * FUNCTION: get_records
- *
- * DESCRIPTION: reads the text records from the input file into a buffer,
- * transforming "\n" to the linefeed character (0x0a)
- ****************************************************************************/
- long get_records(void)
- {
- FILE *infile;
- int rec_count = 0;
- char buf[MAX_LINE_LENGTH];
-
- infile = fopen(infile_name, "rt");
- if (infile) {
- while (!feof(infile) && (rec_count < MAX_RECORDS)) {
- memset(buf, 0, MAX_LINE_LENGTH);
- fgets(buf, MAX_LINE_LENGTH, infile);
- if (strlen(buf)) {
- printf("processing record %d\n", rec_count + 1);
- record[rec_count] = transform(buf);
- rec_count++;
- }
- }
- fclose(infile);
- }
- return(rec_count);
- }
-
- /****************************************************************************
- * FUNCTION: LSwap
- *
- * DESCRIPTION: transforms an INTEL-architecture long int into a MOTOROLLA-
- * architecture long int.
- ****************************************************************************/
- unsigned long LSwap(unsigned long l)
- {
- unsigned short temp_s1, temp_s2;
- unsigned long temp_l;
-
- temp_s1 = SSwap((unsigned short)((l & 0xffff0000) >> 16));
- temp_s2 = SSwap((unsigned short)(l & 0x0000ffff));
- temp_l = ((unsigned long)temp_s2 << 16) + temp_s1;
- return(temp_l);
- }
-
- /****************************************************************************
- * FUNCTION: SSwap
- *
- * DESCRIPTION: transforms an INTEL-architecture short int into a MOTOROLLA-
- * architecture short int.
- ****************************************************************************/
- unsigned short SSwap(unsigned short s)
- {
- unsigned short temp;
-
- temp = ((s & 0xff00) >> 8) + ((s & 0x00ff) << 8);
- return(temp);
- }
-
- /****************************************************************************
- * FUNCTION: transform
- *
- * DESCRIPTION: transforms the passed string, converting "\n" to 0x0a (LF)
- ****************************************************************************/
- char *transform(char *s)
- {
- char *temp_buf;
- char *s1 = s, *s2;
- unsigned char escape = FALSE;
-
- if (strlen(s) > 0) {
- temp_buf = (char *)malloc(strlen(s) + 1);
- memset(temp_buf, 0, strlen(s) + 1);
- s2 = temp_buf;
- while (*s1) {
- if (*s1 == '\\') {
- escape = TRUE;
- }
- else if (*s1 == LF) {
- }
- else {
- if ((*s1 == 'n') && escape) {
- *s2++ = LF;
- escape = FALSE;
- }
- else
- *s2++ = *s1;
- }
- s1++;
- }
- return(temp_buf);
- }
- }
-
-